import os
import unittest
import tempfile
from src.zip_unpact import unpack_folder, remove_garbage_files, unpack_zip
from src.sup_function import get_test_data_path


class FileTest(unittest.TestCase):

    def test_unpack_folder_count_directories(self):
        """
        Тест, проверяющий функцию распаковки директорий: псоле распаковки должно быть известное нам количество директорий.
        :return:
        """
        with tempfile.TemporaryDirectory(dir=get_test_data_path()) as tmp_dir:
            folder_path = os.path.join(get_test_data_path(), 'TestResults')
            unpack_folder(folder_path, tmp_dir)
            self.assertTrue(len([i_name for i_name in os.listdir(tmp_dir)]) == 8)

    def test_remove_garbage_files(self):
        """
        Тест, проверяющий работу фунции удаления файлов, не удовлетворяющих условиям задачи. Создается список файлов,
        которые ожидаемо должны быть удалены. Заданный список сравнивается с полученным в ходе программы.
        :return:
        """
        files_to_delete = []
        remove_garbage_files((os.path.join(get_test_data_path(), 'test_remove_garbage_files')),
                             file_handler=lambda path: files_to_delete.append(os.path.basename(path)))
        self.assertListEqual(sorted(['bisec_c3d_4773.jrn', 'build.log', 'checkout.log', 'console.log',
                                     'concentric_bad.jrn', 'dragging_around_axis_2.jrn', 'short_utest.log']),
                             sorted(files_to_delete))

    def test_unpack_zip(self):
        """
        Тест, проверяющий распаковку zip-архива.
        :return:
        """
        path_directories = os.path.join(get_test_data_path(), 'test_file_zip', 'TestResultsz')
        hash_directories = [hash(i_file) for i_file in os.listdir(path_directories)]
        path_zip = os.path.join(get_test_data_path(), 'test_file_zip', 'TestResultsz.zip')
        with tempfile.TemporaryDirectory(dir=get_test_data_path()) as tmp_dir:
            unpack_zip(path_zip, tmp_dir)
            hash_directories_after = [hash(i_file) for i_file in os.listdir(tmp_dir)]
        self.assertListEqual(hash_directories, hash_directories_after)

    def test_unpack_folder_nested_zips(self):
        """
        Тест, проверяющий распаковку вложенных zip-архивов. Проверяем, чтобы после выполнения программы не было
        директории с названием, которое начинается на "TestResults", а также сравниваем количество директорий до и
        после распаковки.
        :return:
        """
        with tempfile.TemporaryDirectory(dir=get_test_data_path()) as tmp_dir:
            folder_test_path = os.path.join(get_test_data_path(), 'TestResults')
            unpack_folder(folder_test_path, dst=tmp_dir)
            for i_file in os.listdir(tmp_dir):
                with self.subTest(msg=i_file):
                    self.assertTrue('TestResults' not in i_file)
            self.assertTrue(len(os.listdir(folder_test_path)) <
                            len(os.listdir(tmp_dir)))



if __name__ == '__main__':
    unittest.main()
